#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
cron: 20 6 * * *
new Env('联通APP签到&精准任务领取')
功能：1. 每日签到；2. 获取话费红包，可用于充话费
变量：UNICOM_COOKIE，多个账号需建多个UNICOM_COOKIE
脚本日期：2025年9月29日
抓包教程:
    - 打开中国联通APP，打开抓包软件，点击右上角“签到”，结束抓包
    - 搜索 sixPalaceGridTurntableLottery/signin/daySign 的那一条 → 点进去 → “请求” 标签 → 长按 Cookie 那一行 → “复制值”。
    - 填写UNICOM_COOKIE环境变量。
"""

import os
import re
import requests
import time
import json

# ---------- 聚合推送配置 ----------
AGGRE_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'dailylog')
IMMEDIATE = False          # True 实时推送，False 汇总推送

# ---------- 任务过滤设置 ----------
# 设置为True表示启用任务过滤，False表示不启用
ENABLE_TASK_FILTER = True
# 在这个列表中的任务将不会执行（任务名称必须完全匹配）
IGNORE_TASKS = [
    "前往百度地图签到",
    "前往新浪微博签到",
    "观看完整视频广告",
    "中奖率翻5倍",
    "沃百富商城"
]

# 随机延时函数
def human_delay(min_seconds=3, max_seconds=5):
    """模拟人类操作的随机延时"""
    delay_time = time.time() % (max_seconds - min_seconds) + min_seconds
    time.sleep(delay_time)

# ---------- 聚合推送配置 ----------
def push(title, text=""):
    if IMMEDIATE:
        from notify import send
        send(title, text)
    else:
        with open(AGGRE_FILE, "a", encoding="utf-8") as f:
            f.write(f"{title}\n{text}\n{'-'*40}\n")

# ---------- 环境变量读取 ----------
def get_env():
    if "UNICOM_COOKIE" in os.environ:
        cookies = re.split(r'\n|&&', os.environ.get('UNICOM_COOKIE'))
        print(f"✅ 成功读取环境变量，共{len(cookies)}个账号")
        return cookies
    else:
        msg = '❌未添加UNICOM_COOKIE变量'
        print(msg)
        # 保留这个推送以便通知用户配置问题
        push('联通签到&任务', msg)
        exit(0)

# ---------- 执行单个任务 ----------
def execute_task(session, task_id, task_name):
    try:
        # 执行任务的API接口，从抓包信息中提取
        execute_url = f"https://activity.10010.com/sixPalaceGridTurntableLottery/task/completeTask?taskId={task_id}&orderId=&systemCode=QDQD"
        print(f"  🚀 正在执行任务: {task_name} (ID:{task_id})")
        r = session.get(execute_url, timeout=15)
        r.raise_for_status()
        execute_js = r.json()
        
        # 模拟人类操作，添加延时
        human_delay(2, 4)
        
        if execute_js.get("code") == "0000" and execute_js.get("data"):
            # 判断任务执行成功的条件
            if execute_js["data"].get("taskId") == task_id:
                result = f"✅ 执行成功 | 任务ID:{task_id}"
                print(f"    {result}")
                return result
            else:
                result = f"❌ 执行失败 | 原因:返回的任务ID不匹配"
                print(f"    {result}")
                return result
        else:
            result = f"❌ 接口请求失败 | 原因:{execute_js.get('desc', '外层接口异常')}"
            print(f"    {result}")
            return result
    except Exception as e:
        err = str(e)[:50]
        # 特殊处理观看完整视频广告和前往天天领立减金打卡可能的失败
        result = f"❌ 任务执行异常 | 详情:{err}"
        print(f"    {result}")
        return result

# ---------- 判断任务是否已完成（核心逻辑） ----------
def is_task_completed(task):
    """
    根据taskState和buttonName判断任务是否已完成
    返回：(是否已完成, 状态描述)
    """
    task_state = task.get("taskState", 1)
    button_name = task.get("buttonName", "")
    
    # 已完成任务判断条件（满足任一即可）
    if task_state in [2, 3] or button_name in ["已完成", "倒计时"]:
        if task_state == 2 and button_name == "倒计时":
            return (True, "冷却中（已完成，待冷却）")
        elif task_state == 3 and button_name == "已完成":
            return (True, "已完成（可领取/已领取）")
        else:
            return (True, "已领过了")
    # 未完成任务判断条件（需同时满足）
    elif task_state == 1 and any(keyword in button_name for keyword in ["去", "前往"]):
        return (False, "未完成（可操作）")
    # 其他未知状态
    else:
        return (False, f"未知状态（taskState={task_state}, buttonName={button_name}）")

# ---------- 领取单个任务奖励 ----------
def get_task_reward(session, task_id, task_name):
    try:
        reward_url = f"https://activity.10010.com/sixPalaceGridTurntableLottery/task/getTaskReward?taskId={task_id}"
        print(f"  🎁 正在领取任务奖励: {task_name} (ID:{task_id})")
        r = session.get(reward_url, timeout=15)
        r.raise_for_status()
        reward_js = r.json()
        
        # 模拟人类操作，添加延时
        human_delay(1, 3)
        
        if reward_js.get("code") == "0000":
            data = reward_js.get("data", {})
            # 匹配领取成功的关键词（任务完成/领取成功）
            if data.get("code") == "0000" and any(k in data.get("statusDesc", "") for k in ["任务完成", "领取成功"]):
                prize = f"{data.get('prizeName', '未知奖励')}{data.get('prizeCount', '0')}元"
                result = f"✅ {data['statusDesc']} | 奖励:{prize}"
                print(f"    {result}")
                return result
            else:
                err_desc = data.get("statusDesc", "领取失败（未知原因）")
                result = f"❌ 领取失败 | 原因:{err_desc}"
                print(f"    {result}")
                return result
        else:
            result = f"❌ 接口请求失败 | 原因:{reward_js.get('desc', '外层接口异常')}"
            print(f"    {result}")
            return result
    except Exception as e:
        err = str(e)[:50]
        result = f"❌ 异常 | 详情:{err}"
        print(f"    {result}")
        return result

# ---------- 单账号处理（签到+精准任务领取） ----------
def process_one_account(cookie_raw):
    # 提取手机号
    phone_match = re.search(r'u_account=(\d+)', cookie_raw)
    phone = phone_match.group(1) if phone_match else "未知账号"
    
    print(f"\n📱 开始处理账号: {phone}")
    
    # 初始化Session
    session = requests.Session()
    ua = ("Mozilla/5.0 (Linux; Android 12; GM1900 Build/SKQ1.211113.001; wv) "
          "AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/97.0.4692.98 "
          "Mobile Safari/537.36; unicom{version:android@12.0601,desmobile:0};devicetype{deviceBrand:OnePlus,deviceModel:GM1900};OSVersion/12;ltst;")
    headers = {
        "User-Agent": ua,
        "Accept": "application/json, text/plain, */*",
        "Origin": "https://img.client.10010.com",
        "Referer": "https://img.client.10010.com/",
        "X-Requested-With": "com.sinovatech.unicom.ui",
        "Sec-Fetch-Site": "same-site",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Dest": "empty",
        "Accept-Encoding": "gzip, deflate",
        "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
    }
    session.headers.update(headers)
    cookie_dict = {c.split('=', 1)[0]: c.split('=', 1)[1] for c in cookie_raw.split('; ') if '=' in c}
    session.cookies.update(cookie_dict)
    print("  ✅ Session初始化完成")

    try:
        # 1. 每日签到
        sign_result = ""
        sign_r = session.post(
            "https://activity.10010.com/sixPalaceGridTurntableLottery/signin/daySign",
            data="token=", timeout=15
        )
        sign_r.raise_for_status()
        sign_js = sign_r.json()
        sign_desc = sign_js.get("desc", "无描述")
        
        # 模拟人类操作，添加延时
        human_delay(3, 5)
        
        if "已经签到" in sign_desc:
            sign_result = f"===={phone}==== \n\n ✅ 今日已签到"
        elif sign_js.get("code") == "0000" and sign_js.get("data", {}).get("status") == "0000":
            data = sign_js["data"]
            gift = data.get("redSignMessage", "0元")
            petal = data.get("flowerCount", 0)
            sign_result = f"===={phone}==== \n\n ✅ 签到成功 | 现金:{gift} | 花瓣:{petal}"
        else:
            sign_result = f"===={phone}==== \n\n ❌ 签到异常 | 原因:{sign_desc or sign_js}"

        # 2. 获取任务列表
        task_result = "\n"
        print("  🔍 正在获取任务列表...")
        task_r = session.get(
            "https://activity.10010.com/sixPalaceGridTurntableLottery/task/taskList?type=2",
            timeout=15
        )
        task_r.raise_for_status()
        task_js = task_r.json()
        print(f"  ✅ 任务列表获取成功，API返回状态: {task_js.get('code')}")
        
        # 模拟人类操作，添加延时
        human_delay(2, 4)
        
        # 初始化任务列表
        task_list = []
        
        # 响应格式解析
        if task_js.get("code") == "0000" and "data" in task_js:
            # 检查是否有tagList格式
            if "tagList" in task_js["data"]:
                # 遍历所有tag中的任务
                for tag in task_js["data"]["tagList"]:
                    task_dto_list = tag.get("taskDTOList", [])
                    # 为每个任务添加标签信息
                    for task in task_dto_list:
                        task["tagName"] = tag.get("tagName", "无标签")
                        task_list.append(task)
                
                # 检查是否有单独的taskList
                if "taskList" in task_js["data"]:
                    for task in task_js["data"]["taskList"]:
                        task["tagName"] = "其他任务"
                        task_list.append(task)
            # 兼容旧格式
            elif "taskList" in task_js["data"]:
                task_list = task_js["data"]["taskList"]
                for task in task_list:
                    task["tagName"] = "默认标签"
        
        if not task_list:
            task_result += "\n- 暂无可用任务"
        else:
            # 用于收集结果的变量
            total_amount = 0.0
            success_tasks = []
            skipped_tasks = []
            
            for idx, task in enumerate(task_list, 1):
                # 提取任务核心信息
                task_id = task.get("id", "未知ID")
                task_name = task.get("taskName", "未知任务")
                task_reward = task.get("subtitle", "无奖励")
                task_state = task.get("taskState", 1)
                button_name = task.get("buttonName", "未知按钮")
                task_start = task.get("taskStartTime", "未知")
                task_end = task.get("taskEndTime", "未知")
                task_url = task.get("url", "无链接")
                task_tag = task.get("tagName", "无标签")

                # 判断任务是否已完成
                completed, status_desc = is_task_completed(task)

                # 检查任务是否在过滤列表中
                is_ignored = ENABLE_TASK_FILTER and task_name in IGNORE_TASKS

                # 展示任务详情（标注真实状态）
                task_info = (
                    f"\n  [{idx}] 任务名称: {task_name}"
                    f"\n    - 标签: {task_tag} | ID: {task_id} | 奖励: {task_reward} | 真实状态: {status_desc}"
                    f"\n    - 列表状态: taskState={task_state} | 按钮: {button_name}"
                    f"\n    - 时间: {task_start} 至 {task_end} | 链接: {task_url}"
                )
                
                # 如果任务被过滤，完全跳过，不执行任何操作
                if is_ignored:
                    task_info += "\n⚠️ 任务已被过滤，不执行任何操作"
                    skipped_tasks.append(task_name)
                    print(f"  ⚠️  任务 [{task_name}] 已被过滤，完全跳过")
                else:
                    # 仅对未被过滤的任务进行处理
                    # 仅对未完成任务尝试领取奖励
                    if not completed:
                        # 先执行任务
                        execute_task(session, task_id, task_name)
                        
                        # 再尝试领取奖励
                        reward_res = get_task_reward(session, task_id, task_name)
                        
                        # 提取话费红包金额
                        if "✅" in reward_res and "话费红包" in reward_res:
                            # 尝试从奖励文本中提取金额
                            match = re.search(r'话费红包(\d+\.\d+)元', reward_res)
                            if match:
                                amount = float(match.group(1))
                                total_amount += amount
                                success_tasks.append(task_name)
                        
                        # 模拟人类操作，添加任务间延时
                        human_delay(2, 5)
                    else:
                        # 已完成的任务无需处理
                        human_delay(1, 2)
                
            # 构建简化的结果消息
            if success_tasks:
                task_result += f"\n✅ 共计领取话费红包{total_amount:.2f}元[{', '.join(success_tasks)}]"
            
            if skipped_tasks:
                task_result += f"\n⌛ 已跳过任务[{', '.join(skipped_tasks)}]"
            
            # 如果没有成功任务和跳过任务，添加提示
            if not success_tasks and not skipped_tasks:
                task_result += "\n- 所有任务已完成或无需领取"

        # 获取当前账户金额
        r = session.post('https://act.10010.com/SigninApp/convert/getTelephone')
        money = r.json()['data']['telephone']
        task_result += f"\n- 🧧当前话费红包总额: {money}元"
        return f"{sign_result}{task_result}"

    except requests.exceptions.RequestException as e:
        return f"{phone} ❌ 网络异常 | 详情:{str(e)[:100]}"
    except Exception as e:
        return f"{phone} ❌ 解析异常 | 详情:{str(e)[:100]}"

# ---------- 主入口 ----------
def main():
    print("🚀 联通APP签到脚本开始执行")
    print(f"📅 当前时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
    
    cookies = get_env()
    all_results = []
    
    # 账号间添加延时
    for idx, ck in enumerate(cookies):
        if ck.strip():
            print(f"\n===== 开始处理账号 {idx+1}/{len(cookies)} =====")
            result = process_one_account(ck.strip())
            all_results.append(result)
            
            # 如果不是最后一个账号，添加账号间延时
            if idx < len(cookies) - 1:
                print(f"⏱️  账号间延时，等待{5-10}秒...")
                human_delay(5, 10)
    
    content = "\n".join(all_results)
    print("\n" + "="*50)
    print("===== 联通签到&任务汇总 =====")
    print("="*10)
    print(content)
    print("="*10)
    
    # 仅推送最后的汇总结果
    push('联通APP签到任务', content)
    
    print(f"✅ 脚本执行完毕，共处理{len(cookies)}个账号")

# ---------- 本地测试 ----------
if __name__ == "__main__":
    # 本地测试
    # os.environ['UNICOM_COOKIE'] = ''
 
    main()
